/**
 * FileName: DictGroupServiceImpl
 * Author: zlz
 * CreatedDate: 2025/2/26 15:11:59
 * Description:
 * Version: 1.0.0
 */
package com.zlz.open.dict.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zlz.base.entity.response.PageInfo;
import com.zlz.base.entity.response.ResultSet;
import com.zlz.base.enums.DefaultStatusEnum;
import com.zlz.base.enums.DeletedStatusEnum;
import com.zlz.base.enums.EnableStatusEnum;
import com.zlz.base.exception.BizException;
import com.zlz.open.dict.bean.dos.DictGroupEntity;
import com.zlz.open.dict.bean.request.DictGroupRequest;
import com.zlz.open.dict.bean.transfer.DictTransfer;
import com.zlz.open.dict.bean.vo.DictGroupResponse;
import com.zlz.open.dict.dao.DictGroupDao;
import com.zlz.open.dict.service.DictGroupService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;

import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author zlz
 * @date 2025/2/26 15:11:59
 * @description
 */
@Slf4j
@Service
public class DictGroupServiceImpl implements DictGroupService {

    private final DictGroupDao dictGroupDao;

    public DictGroupServiceImpl(DictGroupDao dictGroupDao) {
        this.dictGroupDao = dictGroupDao;
    }

    @Override
    public Mono<ResultSet<Long>> createGroup(Mono<DictGroupRequest> request) {
        return request
                .handle((req, sink) -> {
                    if (StringUtils.isBlank(req.getCode())) {
                        sink.error(new BizException("编码不允许为空"));
                        return;
                    }
                    DictGroupEntity older = dictGroupDao.selectOne(
                            Wrappers.<DictGroupEntity>lambdaQuery()
                                    .eq(DictGroupEntity::getCode, req.getCode())
                    );
                    if (older != null && DeletedStatusEnum.DELETED.getCode().equals(older.getIsDeleted())) {
                        older.setIsDeleted(DeletedStatusEnum.NOT_DELETED.getCode());
                        dictGroupDao.updateById(older);
                        sink.next(ResultSet.success(older.getId()));
                        return;
                    }
                    if (older != null) {
                        sink.error(new BizException("编码重复"));
                        return;
                    }
                    DictGroupEntity dictGroup = DictGroupEntity.builder()
                            .code(req.getCode())
                            .note(req.getNote())
                            .build();
                    int row = dictGroupDao.insert(dictGroup);
                    if (row != 1) {
                        sink.error(new BizException("字段创建失败"));
                        return;
                    }
                    sink.next(ResultSet.success(dictGroup.getId()));
                });
    }

    @Override
    public Mono<ResultSet<PageInfo<DictGroupResponse>>> findByPage(Mono<DictGroupRequest> request) {
        return request
                .<PageInfo<DictGroupResponse>>handle((req, sink) -> {
                    if (req.getPageInfo() == null || req.getPageInfo().getPageNum() == null || req.getPageInfo().getPageSize() == null) {
                        sink.error(new BizException("请补全分页信息"));
                        return;
                    }
                    LambdaQueryWrapper<DictGroupEntity> queryWrapper = Wrappers.lambdaQuery();
                    if (StringUtils.isNotEmpty(req.getCode())) {
                        queryWrapper.like(DictGroupEntity::getCode, req.getCode());
                    }
                    if (StringUtils.isNotEmpty(req.getNote())) {
                        queryWrapper.like(DictGroupEntity::getNote, req.getNote());
                    }
                    if (Objects.nonNull(req.getId())) {
                        queryWrapper.eq(DictGroupEntity::getId, req.getId());
                    }
                    if (Objects.nonNull(req.getStatus())) {
                        queryWrapper.eq(DictGroupEntity::getStatus, req.getStatus());
                    }
                    if (Objects.nonNull(req.getIsDeleted())) {
                        queryWrapper.eq(DictGroupEntity::getIsDeleted, req.getIsDeleted());
                    }
                    if (Objects.nonNull(req.getCreatedTime())) {
                        queryWrapper.between(DictGroupEntity::getCreatedTime,
                                req.getCreatedTime().getStartTime(),
                                req.getCreatedTime().getEndTime());
                    }
                    queryWrapper.orderByDesc(DictGroupEntity::getLastModifiedTime);
                    Page<DictGroupEntity> entityPage = dictGroupDao.selectPage(Page.of(req.getPageInfo().getPageNum(), req.getPageInfo().getPageSize()), queryWrapper);
                    PageInfo<DictGroupResponse> pageInfo = new PageInfo<>();
                    pageInfo.setPageNum(entityPage.getCurrent());
                    pageInfo.setPageSize(entityPage.getSize());
                    pageInfo.setTotalPageNum(entityPage.getPages());
                    pageInfo.setTotalSize(entityPage.getTotal());
                    pageInfo.setList(entityPage.getRecords().stream().map(DictTransfer::transfer).collect(Collectors.toList()));
                    sink.next(pageInfo);
                })
                .map(ResultSet::success);
    }

    @Override
    public Mono<ResultSet<Boolean>> updateGroup(Mono<DictGroupRequest> request) {
        return request.<Integer>handle((req, sink) -> {
            if (req.getCode() == null) {
                sink.error(new BizException("修改字典code不存在"));
                return;
            }
            if (StringUtils.isBlank(req.getNote()) && req.getStatus() == null && req.getIsDeleted() == null) {
                sink.error(new BizException("不存在修改参数"));
                return;
            }
            int row = dictGroupDao.update(DictGroupEntity.builder()
                    .id(req.getId())
                    .code(req.getCode())
                    .note(req.getNote())
                    .status(req.getStatus())
                    .isDeleted(req.getIsDeleted())
                    .build(), Wrappers.<DictGroupEntity>lambdaUpdate().eq(DictGroupEntity::getCode, req.getCode()));
            sink.next(row);
        }).map(row -> row == 1 ? ResultSet.success("修改成功", true) : ResultSet.error("修改失败", false));
    }


    @Override
    public Mono<ResultSet<Boolean>> deletedGroup(Mono<String> code) {
        return code.handle((co, sink) -> {
            if (StringUtils.isBlank(co)) {
                sink.error(new BizException("删除记录id不存在"));
                return;
            }

            DictGroupEntity dictGroupEntity = dictGroupDao.selectOne(Wrappers.<DictGroupEntity>lambdaQuery()
                    .eq(DictGroupEntity::getCode, co)
            );
            if (dictGroupEntity == null) {
                sink.error(new BizException("删除记录id不存在"));
                return;
            }
            if (DeletedStatusEnum.DELETED.getCode().equals(dictGroupEntity.getIsDeleted())) {
                sink.error(new BizException("字典已被删除"));
                return;
            }
            if (DefaultStatusEnum.DEFAULT.getCode().equals(dictGroupEntity.getIsDefault())) {
                sink.error(new BizException("默认配置不允许删除"));
                return;
            }
            dictGroupEntity.setIsDeleted(DeletedStatusEnum.DELETED.getCode());
            int row = dictGroupDao.updateById(dictGroupEntity);
            sink.next(
                    row == 1 ? ResultSet.success(true) : ResultSet.error(false)
            );
        });
    }

    @Override
    public DictGroupEntity selectByCode(String code) {
        if (StringUtils.isBlank(code)) {
            throw new BizException("编码不允许为空");
        }
        DictGroupEntity dictGroupEntity = dictGroupDao.selectOne(Wrappers.<DictGroupEntity>lambdaQuery()
                .eq(DictGroupEntity::getIsDeleted, DeletedStatusEnum.NOT_DELETED.getCode())
                .eq(DictGroupEntity::getStatus, EnableStatusEnum.ENABLE.getCode())
                .eq(DictGroupEntity::getCode, code));

        if (dictGroupEntity == null) {
            throw new BizException("字典不存在或者已被删除或禁用");
        }
        return dictGroupEntity;
    }
}
